﻿using BLevy.Datos.Repositories;
using BLevy.Entidad;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using MySql.Data.MySqlClient;
using System.Configuration;

namespace BLevy.Negocio
{
    public class Periodos
    {
        public static IList<Periodo> FindAll()
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.FindAll();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static Periodo FindById(int id)
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.FindById(id);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static Periodo FindLast()
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.FindLast();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static Periodo FindByPeriodo(string periodo)
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.FindByPeriodo(periodo);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static int Add(Periodo newEntity)
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.Add(newEntity);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static int Modify(Periodo entity)
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.Modify(entity);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static int Remove(int id)
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.Remove(id);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static int GenerarPeriodo(Periodo _periodo)
        {
            int generacion = 0;

            try
            {
                string periodo = _periodo.periodo.ToString("MM/yyyy");
                Periodo existe = FindByPeriodo(periodo);

                if (existe == null)
                {
                    Datos.Repositories.SocioRepository socioRepository = new SocioRepository();
                    Datos.Repositories.AdherenteRepository adherenteRepository = new AdherenteRepository();
                    Datos.Repositories.PeriodoSocioRepository periodoSocioRepository = new PeriodoSocioRepository();
                    Datos.Repositories.PeriodoRepository periodoRepository = new PeriodoRepository();
                    Datos.Repositories.DeudaRepository deudaRepository = new DeudaRepository();


                    IList<Socio> sociosL;
                    sociosL = socioRepository.FindAll().ToList();

                    double cuota;
                    using (TransactionScope scope = new TransactionScope())
                    {
                        int resultado = periodoRepository.Add(_periodo);

                        using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                        {
                            _db.Open();

                            try
                            {
                                if (resultado != 0)
                                {
                                    bool res = true;

                                    int idPeriodo = FindLast().id;

                                    foreach (var socio in sociosL)
                                    {
                                        cuota = new double();

                                        //buscar adherentes por socio
                                        socio.adherentes = adherenteRepository.FindByIdSocioActivos(socio.id);

                                        //calcular importe de la cuota por socio
                                        if(Convert.ToBoolean(socio.cuotafija) == true)
                                            cuota = ((socio.cuota + socio.recargo) - socio.bonificacion);
                                        else
                                            cuota = periodoSocioRepository.CalcularCuota(socio);
                                                
                                        //verificar si el socio se debe dar de baja por 3 periodos impagos
                                        if (socio.activo == 1)
                                        {
                                            int impagos = PeriodosSocios.FindAllImpagosBySocioId(socio.id).Count;

                                            if (impagos >= 3)
                                            {
                                                SocioBaja baja = new SocioBaja();
                                                baja.socio_id = socio.id;
                                                baja.fecha = DateTime.Now;
                                                baja.motivo = "ACUMULA 3 PERIODOS IMPAGOS.";
                                                baja.operacion = "B";
                                                baja.tipo_baja = "A";

                                                Socios.SocioBaja(socio.id, baja);
                                            }
                                        }


                                        //verificar si posee deuda
                                        Deuda _deuda = deudaRepository.ConsultarDeudaPorSocio(socio);

                                        //modificar el estado de la deuda ya que pasa al periodo
                                        if (_deuda != null)
                                        {
                                            cuota += _deuda.saldo;

                                            _deuda.estado = "P";

                                            int resDeuda = deudaRepository.ModificarDeuda(_deuda);

                                            if (resDeuda == 0)
                                            {
                                                res = false;
                                                break;
                                            }
                                        }

                                        //generar periodos por socio
                                        PeriodoSocio _periodosocio = new PeriodoSocio();
                                        _periodosocio.periodo_id = idPeriodo;
                                        _periodosocio.socio_id = socio.id;
                                        _periodosocio.importe = cuota;
                                        _periodosocio.estado = "I";

                                        if (periodoSocioRepository.Add(_periodosocio) == 0)
                                        {
                                            res = false;
                                            break;
                                        }
                                    }

                                    if (res == true)
                                    {
                                        //genero los cupones//////////////////////
                                        int cupon = Cupones.GenerarCupon();
                                        if (cupon > 0)
                                        {
                                            scope.Complete();

                                            generacion = 1;
                                        }
                                        else
                                        {
                                            generacion = 0;

                                            cupon = 0;
                                        }

                                        //////////////////////////////////////
                                    }
                                    else
                                    {
                                        generacion = 0;
                                    }
                                }
                            }
                            catch
                            {
                                generacion = 0;
                            }
                        }
                    }
                }
                else
                {
                    generacion = -2;
                }
            }
            catch (Exception e)
            {
                throw e;
            }


            return generacion;
        }

        public static IList<Periodo> GetPeriodosByIdCupon(int cupon_id)
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.GetPeriodosByIdCupon(cupon_id);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static int RegistrarMensaje(PeriodoMensaje periodo_mensaje)
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.RegistrarMensaje(periodo_mensaje);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static string FindMensajeMasivoPeriodo(int periodo_id)
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.FindMensajeMasivoPeriodo(periodo_id);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static int VerificarMensajePeriodo(int periodo_id)
        {
            try
            {
                IPeriodoRepository _repository = new PeriodoRepository();
                return _repository.VerificarMensajePeriodo(periodo_id);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }
}
